package com.zq.blog_serve.service.flowable;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zq.blog_serve.entity.condition.BaseCondition;
import com.zq.blog_serve.entity.flowable.DeploymentResponse;
import com.zq.blog_serve.entity.flowable.ProcessDefinitionDTO;
import org.apache.commons.io.IOUtils;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ProcessDefinitionService {

    @Autowired
    RepositoryService repositoryService;

    // 查询流程定义列表
    public Page getProcessDefinitions(BaseCondition condition) {
        ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
        long total = query.count();
        List<ProcessDefinitionDTO> collect = query.listPage((condition.getCurrentPage() - 1) * condition.getPageSize(), condition.getPageSize()).stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
        Page page = new Page();
        page.setTotal(total);
        page.setRecords(collect);
        return page;
    }

    // 按ID查询流程定义
    public ProcessDefinitionDTO getProcessDefinitionById(String processDefinitionId) {
        ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(processDefinitionId)
                .singleResult();
        String xml = "";
        try (InputStream inputStream = repositoryService.getResourceAsStream(
                pd.getDeploymentId(),
                pd.getResourceName())) {
            xml = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new RuntimeException("Failed to read process definition XML", e);
        }
        return pd != null ? convertToDTO(pd, xml) : null;
    }

    // 部署流程定义（修改后的方法）
    public DeploymentResponse deployProcessDefinition(String name, String xml) {
        try {
            // 使用固定文件名或根据实际情况生成
            String resourceName = name.toLowerCase().replace(" ", "-") + ".bpmn20.xml";

            Deployment deployment = repositoryService.createDeployment()
                    .name(name)
                    .addString(resourceName, xml)
                    .deploy();

            return DeploymentResponse.builder()
                    .id(deployment.getId())
                    .name(deployment.getName())
                    .success(true)
                    .message("部署成功")
                    .build();
        } catch (Exception e) {
            return DeploymentResponse.builder()
                    .success(false)
                    .message("部署失败: " + e.getMessage())
                    .build();
        }
    }

    // 挂起流程定义
    public void suspendProcessDefinition(String processDefinitionId) {
        repositoryService.suspendProcessDefinitionById(processDefinitionId);
    }

    // 激活流程定义
    public void activateProcessDefinition(String processDefinitionId) {
        repositoryService.activateProcessDefinitionById(processDefinitionId);
    }

    // 删除部署
    public void deleteDeployment(String deploymentId) {
        repositoryService.deleteDeployment(deploymentId);
    }

    // 转换实体为DTO
    private ProcessDefinitionDTO convertToDTO(ProcessDefinition pd, String xml) {
        ProcessDefinitionDTO dto = new ProcessDefinitionDTO();
        dto.setId(pd.getId());
        dto.setName(pd.getName());
        dto.setKey(pd.getKey());
        dto.setVersion(pd.getVersion());
        dto.setDeploymentId(pd.getDeploymentId());
        dto.setResourceName(pd.getResourceName());
        dto.setDiagramResourceName(pd.getDiagramResourceName());
        dto.setSuspended(pd.isSuspended());
        dto.setXml(xml);

        // 获取部署时间
        // Deployment deployment = repositoryService.createDeploymentQuery()
        //         .deploymentId(pd.getDeploymentId())
        //         .singleResult();
        // if (deployment != null) {
        //     dto.setDeploymentTime(deployment.getDeploymentTime());
        // }
        return dto;
    }

    private ProcessDefinitionDTO convertToDTO(ProcessDefinition pd) {
        ProcessDefinitionDTO dto = new ProcessDefinitionDTO();
        dto.setId(pd.getId());
        dto.setName(pd.getName());
        dto.setKey(pd.getKey());
        dto.setVersion(pd.getVersion());
        dto.setDeploymentId(pd.getDeploymentId());
        dto.setResourceName(pd.getResourceName());
        dto.setDiagramResourceName(pd.getDiagramResourceName());
        dto.setSuspended(pd.isSuspended());

        // 获取部署时间
        // Deployment deployment = repositoryService.createDeploymentQuery()
        //         .deploymentId(pd.getDeploymentId())
        //         .singleResult();
        // if (deployment != null) {
        //     dto.setDeploymentTime(deployment.getDeploymentTime());
        // }
        return dto;
    }
}
